package com.castrianni.vcs.cvs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import javax.swing.JTextArea;

import org.jgraph.JGraph;
import org.jgraph.graph.CellView;
import org.jgraph.graph.DefaultGraphCell;
import com.castrianni.vcs.VcsBranch;
import com.castrianni.vcs.VcsRevisionGraphCellViewFactory;
import com.castrianni.vcs.VcsRevisionGraphRevision;
import com.intellij.cvsSupport2.history.CvsFileRevision;
import com.intellij.openapi.project.Project;
import info.clearthought.layout.TableLayout;

public class CVSRevisionGraphCellViewFactory extends VcsRevisionGraphCellViewFactory {
  public static final String DEAD_STATE = "dead";

  protected boolean _showTags = true;
  protected boolean _showTagFilter = false;
  protected String _tagFilter = null;

  public CVSRevisionGraphCellViewFactory(Project project)
  {
    super(project);
  }

  protected VcsRevisionVertexRenderer createRevisionVertexRenderer()
  {
    return(new CVSRevisionVertexRenderer());
  }

  protected VcsBranchVertexRenderer createBranchVertexRenderer()
  {
    return(new CVSBranchVertexRenderer());
  }

  public boolean isShowTags()
  {
    return(_showTags);
  }

  public void setShowTags(boolean showTags)
  {
    _showTags = showTags;
  }

  public String getTagFilter()
  {
    return(_tagFilter);
  }

  public void setTagFilter(String tagFilter)
  {
    _tagFilter = tagFilter;
  }

  public boolean isShowTagFilter()
  {
    return _showTagFilter;
  }

  public void setShowTagFilter(boolean showTagFilter)
  {
    _showTagFilter = showTagFilter;
  }

  protected class CVSBranchVertexRenderer extends VcsBranchVertexRenderer {
    protected JLabel _revision = null;

    public CVSBranchVertexRenderer()
    {
      super();
      TableLayout tl = (TableLayout)_panel.getLayout();
      tl.insertRow(1,TableLayout.PREFERRED);
      _revision = new JLabel();
      _panel.add(_revision,"0,1,c,f");
    }

    public Component getRendererComponent(JGraph graph,CellView view,boolean selected,boolean focus,boolean preview)
    {
      super.getRendererComponent(graph,view,selected,focus,preview);
      DefaultGraphCell cell = (DefaultGraphCell)view.getCell();
      VcsBranch branchRevision = (VcsBranch)cell.getUserObject();
      if(branchRevision.getId().equals("1")) {
        _revision.setText("");
        _revision.setVisible(false);
      } else {
        _revision.setText(branchRevision.getId());
        _revision.setVisible(true);
      }
      if(selected)
        _revision.setForeground(Color.white);
      else
        _revision.setForeground(Color.black);
      return(_panel);
    }
  }

  protected class CVSRevisionVertexRenderer extends VcsRevisionVertexRenderer {
    protected JSeparator _sep = null;
    protected JTextArea _ta = null;

    public CVSRevisionVertexRenderer()
    {
      super();
      TableLayout tl = (TableLayout)_panel.getLayout();
      tl.insertRow(1,TableLayout.PREFERRED);
      _sep = new JSeparator(JSeparator.HORIZONTAL);
      _panel.add(_sep,"0,1,1,1,f,f");
      tl.insertRow(2,TableLayout.PREFERRED);
      _ta = new JTextArea();
      _panel.add(_ta,"0,2,1,2");
    }

    public Component getRendererComponent(JGraph graph,CellView view,boolean selected,boolean focus,boolean preview)
    {
      super.getRendererComponent(graph,view,selected,focus,preview);
      DefaultGraphCell cell = (DefaultGraphCell)view.getCell();
      VcsRevisionGraphRevision rev = (VcsRevisionGraphRevision)cell.getUserObject();
      CvsFileRevision cRev = (CvsFileRevision)rev.getFileRevision();
      boolean isDead = false;
      ArrayList<String> revLabels = null;
      if(_showTags) {
        if(cRev.getState().equals(DEAD_STATE))
          isDead = true;
        //noinspection unchecked
        Collection<String> revLabelsC = cRev.getTags();
        if(revLabelsC != null) {
          revLabels = new ArrayList<String>(revLabelsC);
          Collections.sort(revLabels);
        }
        //Filter labels based on configuration
        if((revLabels != null) && (_tagFilter != null) && (_tagFilter.length() > 0)) {
          for(int i = (revLabels.size() - 1); i >= 0; i--) {
            String revLabel = revLabels.get(i);
            boolean matches = revLabel.matches(_tagFilter);
            if(_showTagFilter ? !matches : matches)
              revLabels.remove(i);
          }
        }
      }
      if(isDead)
        _revision.setText("(" + rev.getRevisionNumber().asString() + ")");
      if(selected) {
        if(isDead) {
          _panel.setBackground(_revisionDeletedSelectedColor);
          _ta.setBackground(_revisionDeletedSelectedColor);
        } else
          _ta.setBackground(_revisionSelectedColor);
        _sep.setForeground(Color.white);
        _ta.setForeground(Color.white);
      } else {
        if(isDead) {
          _panel.setBackground(_revisionDeletedColor);
          _ta.setBackground(_revisionDeletedColor);
        } else
          _ta.setBackground(_revisionColor);
        _sep.setForeground(Color.black);
        _ta.setForeground(Color.black);
      }
      //Add separator
      TableLayout tl = (TableLayout)_panel.getLayout();
      if((revLabels != null) && (revLabels.size() > 0)) {
        _sep.setVisible(true);
        _ta.setVisible(true);
        tl.setRow(1,TableLayout.PREFERRED);
        tl.setRow(2,TableLayout.PREFERRED);
        StringBuffer labels = new StringBuffer();
        for(String revLabel : revLabels) {
          if(labels.length() != 0)
            labels.append("\n");
          labels.append(revLabel);
        }
        _ta.setText(labels.toString());
      } else {
        _sep.setVisible(false);
        _ta.setVisible(false);
        tl.setRow(1,0.0);
        tl.setRow(2,0.0);
        _ta.setText(null);
      }
      return(_panel);
    }
  }
}
